package com.geline.web.interceptor;

import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.geline.web.annotation.ValidBefore;
import com.geline.web.annotation.ValidBefores;
import com.geline.web.handler.ValidBeforeHandler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cglib.beans.BeanMap;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.HandlerMapping;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
 * 前置拦截器
 * 使用方式：
     @Override
     public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new ValidBeforeInterceptor()).addPathPatterns("/**");
     }
 *
 * @author: mx
 * @date: 2024-07-16 10:07
 */
@Slf4j
public class ValidBeforeInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if (handler instanceof HandlerMethod) {
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            Method method = handlerMethod.getMethod();
            List<ValidBefore> list = new ArrayList<>();
            ValidBefore validBefore = method.getAnnotation(ValidBefore.class);
            ValidBefores validBefores = method.getAnnotation(ValidBefores.class);
            if(validBefore != null){
                list.add(validBefore);
            }else if (validBefores != null) {
                list.addAll(Arrays.asList(validBefores.value()));
            }
            if(list.size() > 0){
                Map<String, Object> pathVars = (Map<String, Object>) request.getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE);
                list.stream().forEach(row -> {
                    String paraName = row.idVariable();
                    if(StrUtil.isNotBlank(paraName)){
                        if(paraName.contains(".")){
                            String[] split = paraName.split(".");
                            String parentName = split[0];
                            String idName = split[1];
                            Object object = pathVars.get(parentName);
                            Object idValue = BeanMap.create(object).get(idName);
                            handle(row, String.valueOf(idValue));
                        }else {
                            Object idValue = pathVars.get(paraName);
                            handle(row, (String)idValue);
                        }
                    }else {
                        handle(row, pathVars);
                    }
                });
            }
        }
        return true;
    }

    private void handle(ValidBefore validBefore, Map<String, Object> pathVars) {
        Class<? extends ValidBeforeHandler> handler = validBefore.handler();
        ValidBeforeHandler beforeHandler = SpringUtil.getBean(handler);
        if(!beforeHandler.doHandle(pathVars)){
            throw new RuntimeException(validBefore.errorMsg());
        }
    }

    private void handle(ValidBefore validBefore, String idValue){
        //获取删除的所有id
        List<String> idList = Arrays.asList(idValue.split(","));
        for(String id : idList){
            Class<? extends ValidBeforeHandler> handler = validBefore.handler();
            ValidBeforeHandler beforeHandler = SpringUtil.getBean(handler);
            if(!beforeHandler.doHandle(id)){
                throw new RuntimeException(validBefore.errorMsg());
            }
        }
    }
}
